package com.kakame.tibbers.common.directive;

import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;
import com.kakame.tibbers.common.init.cache.ResourceCache;
import com.kakame.tibbers.common.models.AuthResource;

/**
 * 权限指令
 * <pre>
 * 使用方式：
 * 
 * #auth('1', 'backend')
 * 
 * #end
 * </pre>
 * @author 何家明
 * @date 2018年11月24日 下午7:55:26
 */
public class AuthDirective extends Directive {
	
	/** 当前登录用户的id */
	private Expr currentUserIdExpr;
	/** t_auth_resource 表中的resource_code*/
	private Expr resourceCodeExpr;

	@Override
	public void setExprList(ExprList exprList) {
		int paramNum = exprList.length();  // 参数个数
		if(paramNum != 2) {
			throw new ParseException("auth指令中应当有且仅有两个参数", location);
		}
		this.currentUserIdExpr = exprList.getExpr(0);
		this.resourceCodeExpr = exprList.getExpr(1);
	}

	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		Object currentUserIdObj = currentUserIdExpr.eval(scope);
		if(currentUserIdObj == null) {
			return;
		}
		Object resourceCodeObj = resourceCodeExpr.eval(scope);
		String resourceCode = String.valueOf(resourceCodeObj);
		String currentUserId = String.valueOf(currentUserIdObj);
		
		boolean existAuth = ResourceCache.me.hasAuth(resourceCode);
		if(!existAuth) {
			throw new TemplateException("resource_code值为" + resourceCode + "的这条权限不存在，请检查！", location);
		}
		
		boolean hasAuth = false;
		List<AuthResource> userAuths = ResourceCache.me.getUserAuths(currentUserId);
		for (AuthResource authResource : userAuths) {
			if(StringUtils.equals(resourceCode, authResource.getResourceCode())) {
				hasAuth = true;
				break;
			}
		}
		if(hasAuth) {
			stat.exec(env, scope, writer);  // 执行 body
		}
	}

	@Override
	public boolean hasEnd() {
		return true;
	}
}
